#include "daemon_sub_process.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/reboot.h>
#include <signal.h>
#include "log.h"



//1  初始化自己 填写子进程的相关参数 ： 程序名 参数 
sub_process_t *daemon_sub_process_init(char *sub_cmd)
{
	//1 初始化结构体
	sub_process_t *sub_process = (sub_process_t *)malloc(sizeof(sub_process_t));
	//2 初始值
	sub_process->sub_cmd = sub_cmd;
	sub_process->fail_count=0;
	sub_process->pid = -1;

	return sub_process;

}

//2  检查并启动子进程 
//   检查 waitpid 根据 返回值 和 状态status
//  启动就是用fork execve 启动子进程
int daemon_sub_process_check_start(sub_process_t *sub_process)
{	
    int exit_status;

	//1 检查 // 启动过且当前存活
	if(sub_process->pid != -1 && waitpid(sub_process->pid,&exit_status,WNOHANG) ==0) 
	{
		return 0; //程序正在运行无需处理
	}
	// 要么没启动 要么夭折了
	//  如果是异常结束 失败计数+1 达到阈值重启系统
	if(exit_status != 0)
	{
		sub_process->fail_count++;
		if(sub_process->fail_count >= MAX_FAIL_COUNT)
		{
			log_error("sub process exit too many times,restart the system\n");
			reboot(RB_AUTOBOOT);
		}
	}
	// 2 重启子进程
	// fork  execve 
	sub_process->pid = fork();
	if(sub_process->pid == 0)
	{
		// 子进程
		// execve启动进程 //1 启动命令 2 参数列表 3 环境变量
		char *argv[3] = {EXE_NAME,sub_process->sub_cmd,NULL};
	    char *envp[] = {NULL};
		int ret=execve(EXE_NAME,argv,envp);
		if(ret != 0)
		{
			log_error("execve %s 执行失败",sub_process->sub_cmd);
			_exit(EXIT_FAILURE);
		}
		
	}

	return 0;


}

//3  子进程结束
// kill 掉 
// 回收相关资源
void daemon_sub_process_exit(sub_process_t *sub_process)
{
	kill(sub_process->pid,SIGTERM);
	waitpid(sub_process->pid,NULL,WUNTRACED);
	free(sub_process);
}